package org.zhaya;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import org.zhaya.sdk.processors.AddFieldProcessor;
import org.zhaya.sdk.processors.AddUUIDProcessor;
import org.zhaya.sdk.processors.AnonymizeProcessor;
import org.zhaya.sdk.processors.ColumnsToJSONStringProcessor;
import org.zhaya.sdk.processors.CompareAndSetProcessor;
import org.zhaya.sdk.processors.ConvertFieldProcessor;
import org.zhaya.sdk.processors.DateProcessor;
import org.zhaya.sdk.processors.ExtractFieldProcessor;
import org.zhaya.sdk.processors.FilterProcessor;
import org.zhaya.sdk.processors.GrokProcessor;
import org.zhaya.sdk.processors.JsonObjectaAndStringProcessor;
import org.zhaya.sdk.processors.JsonSortProcessor;
import org.zhaya.sdk.processors.LowerCaseProcessor;
import org.zhaya.sdk.processors.MathProcessor;
import org.zhaya.sdk.processors.NumberExchangeProcessor;
import org.zhaya.sdk.processors.RenameFieldProcessor;
import org.zhaya.sdk.processors.ScriptProcessor;
import org.zhaya.sdk.processors.TransposeProcessor;
import org.zhaya.sdk.processors.URLDecodeProcessor;
import org.zhaya.sdk.processors.XmlProcessor;
import org.zhaya.sdk.processors.custom.SourceCodeTypeEnum;
import io.logz.sawmill.processors.*;
import org.zhaya.sdk.PipelineServiceFactory;
import org.zhaya.sdk.constant.LogicEnum;
import org.zhaya.sdk.constant.OperatorEnum;
import org.zhaya.sdk.model.ProcessorNode;
import org.zhaya.sdk.processors.TranslateProcessor;
import org.zhaya.sdk.processors.UpperCaseProcessor;

import java.util.Arrays;
import java.util.Collections;

/**
 * @Author Ryan Yang
 * @Date 2022/10/11 5:25 下午
 */
public class ProcessorBuildExample {

    //sawmill组件构造
    //drop(丢弃数据)
    public static ProcessorNode dropProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("percentage", 100)), DropProcessor.Configuration.class)
            .build();
    //geoIp(GeoIP)
    public static ProcessorNode geoIpProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("sourceField", "ip"), MapUtil.entry("targetField", "geoip"), MapUtil.entry("tagsOnSuccess", Collections.singletonList("geo-ip"))), GeoIpProcessor.Configuration.class)
            .build();
    //csv(CSV解析)
    public static ProcessorNode csvProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("field", "message"), MapUtil.entry("separator", ","), MapUtil.entry("columns", Arrays.asList("ip", "date", "level", "info")), MapUtil.entry("skipEmptyColumns", false), MapUtil.entry("autoGenerateColumnNames", true)), CsvProcessor.Configuration.class)
            .build();
    //gsub(正则替换)
    public static ProcessorNode gsubProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("field", "phone"), MapUtil.entry("pattern", "(?<=^[0-9]{3})[0-9]substring{4}"), MapUtil.entry("replacement", " **** ")), SubstituteProcessor.Configuration.class)
            .build();
    //addTag(添加Tag)
    public static ProcessorNode addTagProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("tags", Collections.singletonList("tagName"))), AddTagProcessor.Configuration.class)
            .build();
    //removeField(删除字段)
    public static ProcessorNode removeFieldProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("fields", Collections.singletonList("fieldName"))), RemoveFieldProcessor.Configuration.class)
            .build();
    //substring(定长字段提取)
    public static ProcessorNode substringProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("field", "fieldName"), MapUtil.entry("begin", 1), MapUtil.entry("end", 2)), SubstringProcessor.Configuration.class)
            .build();
    //translate(字典替换)
    public static ProcessorNode translateProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("field", "deviceTypeId"), MapUtil.entry("targetField", "deviceType"), MapUtil.entry("dictionary", MapUtil.ofEntries(MapUtil.entry("0", "Unknown"), MapUtil.entry("1", "Windows"), MapUtil.entry("2", "Mac")))), TranslateProcessor.Configuration.class)
            .build();
    //strip(去除空白)
    public static ProcessorNode stripProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("field", Collections.singletonList("fieldName"))), StripProcessor.Configuration.class)
            .build();
    //split(字段分割)
    public static ProcessorNode splitProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("field", "fieldName"), MapUtil.entry("separator", "\\.")), SplitProcessor.Configuration.class)
            .build();
    //arraysIntersect(列表交集)
    public static ProcessorNode arraysIntersectProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("sourceFieldA", "fielddNameA"), MapUtil.entry("sourceFieldB", "fielddNameB"), MapUtil.entry("targetField", "targetFieldName")), ArraysIntersectProcessor.Configuration.class)
            .build();
    //removeTag(删除Tag)
    public static ProcessorNode removeTagProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("tags", Collections.singletonList("tagName"))), RemoveTagProcessor.Configuration.class)
            .build();
    //ahoCorasick(AC模式匹配)
    public static ProcessorNode ahoCorasickProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("field", "message"), MapUtil.entry("targetField", "after"), MapUtil.entry("inputWords", Arrays.asList("like", "you"))), AhoCorasickProcessor.Configuration.class)
            .build();
    //userAgent(User Agent)
    public static ProcessorNode userAgentProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("field", "userAgent"), MapUtil.entry("prefix", "UA-")), UserAgentProcessor.Configuration.class)
            .build();
    //docSize(计算doc字符长度)
    public static ProcessorNode docSizeProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("targetField", "docSize")), DocSizeProcessor.Configuration.class)
            .build();
    //kv(KV提取)
    public static ProcessorNode kvProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("field", "data"), MapUtil.entry("targetField", "message"), MapUtil.entry("fieldSplit", "&"), MapUtil.entry("valueSplit", "="), MapUtil.entry("trim", StrUtil.UNDERLINE)), KeyValueProcessor.Configuration.class)
            .build();
    //appendList(增加列表字段)
    public static ProcessorNode appendListProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("targetField", "docSize")), AppendListProcessor.Configuration.class)
            .build();
    //upperCase(转大写)
    public static ProcessorNode upperCaseProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("fields", Collections.singletonList("fieldName"))), UpperCaseProcessor.Configuration.class)
            .build();
    //externalMapping(外部映射)
    public static ProcessorNode externalMappingProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("sourceField", "sourceFieldName"), MapUtil.entry("targetField", "targetFieldName"), MapUtil.entry("mappingSourceUrl", "http://10.1.10.1:10101/mapping")), ExternalMappingSourceProcessor.Configuration.class)
            .build();
    //deDot(key连接符替换)
    public static ProcessorNode deDotProcessor = PipelineServiceFactory.processorNodeBuilder()
            .configMap(MapUtil.ofEntries(MapUtil.entry("separator", StrUtil.UNDERLINE)), DeDotProcessor.Configuration.class)
            .build();

    //dodp-sdk组件构造
    //date(日期转换)
    public static ProcessorNode dateProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            DateProcessor.Configuration.builder().field("time1").targetField("time").timeZone("Asia/Shanghai").formats(Arrays.asList("yyyy.MM.dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.SSS")).targetFormat(DateProcessor.TargetFormat.UNIX_MS).build()).build();
    //numberExchange(进制转换)
    public static ProcessorNode numberExchangeProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            NumberExchangeProcessor.Configuration.builder().fields(Collections.singletonList("fieldName")).in_radix(2).out_radix(10).build()).build();
    //convert(字段类型转换)
    public static ProcessorNode convertProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            ConvertFieldProcessor.Configuration.builder().path("message.head").type(ConvertFieldProcessor.FieldType.INT).build()).build();
    //urldecode(URL解码)
    public static ProcessorNode urldecodeProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            URLDecodeProcessor.Configuration.builder().field("fieldName").targetField("targetFieldName").build()).build();
    //dataFilter
    public static ProcessorNode dataFilterProcessor = PipelineServiceFactory.processorNodeBuilder().config(FilterProcessor.Configuration.builder()
            .criteria(Arrays.asList(
                    FilterProcessor.Criteria.builder()
                            .logic(LogicEnum.AND.getValue())
                            .condition(Collections.singletonList(FilterProcessor.Condition.builder().operator(OperatorEnum.gte.name()).field("fieldName").value(0).build()))
                            .drop(true)
                            .build(),
                    FilterProcessor.Criteria.builder()
                            .logic(LogicEnum.AND.getValue())
                            .condition(Collections.emptyList())
                            .drop(false)
                            .build()
            )).build()).build();
    //xml(XML解析)
    public static ProcessorNode xmlProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            XmlProcessor.Configuration.builder().field("xmlFieldName").targetField("targetFieldName").storeXml(true).xpath(MapUtil.ofEntries(MapUtil.entry("/user/name", "username"))).build()).build();
    //addUUID(添加UUID)
    public static ProcessorNode addUUIDProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            AddUUIDProcessor.Configuration.builder().targetField("fieldName").build()).build();
    //lowerCase(转小写)
    public static ProcessorNode lowerCaseProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            LowerCaseProcessor.Configuration.builder().field(Collections.singletonList("fieldName")).build()).build();
    //columnsToJSONString(JSON String)
    public static ProcessorNode columnsToJSONStringProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            ColumnsToJSONStringProcessor.Configuration.builder().sourceFields(Collections.singletonList("fieldName")).targetField("targetFieldName").build()).build();
    //json(JSON转换)
    public static ProcessorNode jsonProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            JsonObjectaAndStringProcessor.Configuration.builder().field("fieldName").targetField("targetFieldName").theWay(JsonObjectaAndStringProcessor.TheWays.STRINGTOOBJECT.name()).build()).build();
    //extractField(字段提取)
    public static ProcessorNode extractFieldProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            ExtractFieldProcessor.Configuration.builder().fieldList(Arrays.asList("a", "b")).build()).build();
    //anonymize(数据脱敏)
    public static ProcessorNode anonymizeProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            AnonymizeProcessor.Configuration.builder().fields(Arrays.asList("a", "b")).algorithm(AnonymizeProcessor.Algorithm.MD5).key("key").build()).build();
    //addField(添加字段)
    public static ProcessorNode addFieldProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            AddFieldProcessor.Configuration.builder().config(Collections.singletonList(MapUtil.ofEntries(MapUtil.entry("path", "message.name"), MapUtil.entry("value", "test")))).build()).build();
      //jsonSort(JSON排序)
    public static ProcessorNode jsonSortProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            JsonSortProcessor.Configuration.builder().config(Collections.singletonList(MapUtil.ofEntries(MapUtil.entry("field", "fieldName"), MapUtil.entry("targetField", "targetFieldName"), MapUtil.entry("type", "jsonString"), MapUtil.entry("sortType", "asc")))).build()).build();
    //rename(重命名字段)
    public static ProcessorNode renameProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            RenameFieldProcessor.Configuration.builder().config(Collections.singletonList(MapUtil.ofEntries(MapUtil.entry("from", "name"), MapUtil.entry("to", "username")))).build()).build();
    //compareAndSet(数据赋值)
    public static ProcessorNode compareAndSetProcessor = PipelineServiceFactory.processorNodeBuilder().config(CompareAndSetProcessor.Configuration.builder()
            .criteria(Arrays.asList(
                    CompareAndSetProcessor.Criteria.builder()
                            .logic(LogicEnum.AND.getValue())
                            .condition(Collections.singletonList(CompareAndSetProcessor.Condition.builder().operator(OperatorEnum.gte.name()).field("a").value(0).build()))
                            .then(CompareAndSetProcessor.Then.builder().targetField("b").targetValue(3).build())
                            .build(),
                    CompareAndSetProcessor.Criteria.builder()
                            .logic(LogicEnum.AND.getValue())
                            .condition(Collections.singletonList(CompareAndSetProcessor.Condition.builder().operator(OperatorEnum.def.name()).field(StrUtil.EMPTY).value(StrUtil.EMPTY).build()))
                            .then(CompareAndSetProcessor.Then.builder().targetField(StrUtil.EMPTY).targetValue(StrUtil.EMPTY).build())
                            .build()
            )).build()).build();
    //grok(grok拆分)
    public static ProcessorNode grokProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            GrokProcessor.Configuration.builder().field("message").overwrite(Collections.singletonList("_cw_message")).ignoreMissing(true).patterns(Collections.singletonList("%{HOSTNAME:host} %{DAY:week} %{WORD:month} %{MONTHDAY:day} %{TIME:time} %{TZ:biaozhun} %{YEAR:year} \\[%{WORD:level}\\] %{NOTSPACE:info}")).build()).build();

    //math(数据运算)
    public static ProcessorNode mathProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            MathProcessor.Configuration.builder().expression("{{a}}/{{b}}").targetField("result").build()).build();

    //transpose(列转换)
    public static ProcessorNode transposeProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            TransposeProcessor.Configuration.builder().fields(Collections.singletonList("fieldName")).targetNameField("targetFieldName").targetValueField("targetValue").build()).build();

    //script(脚本)
    public static ProcessorNode scriptProcessor = PipelineServiceFactory.processorNodeBuilder().config(
            ScriptProcessor.Configuration.builder().sourceCodeType(SourceCodeTypeEnum.Java).sourceCode("java soruce code").build()).build();
}
